package com.dituhui.tool.io;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;

import com.dituhui.tool.gis.Point;
import com.dituhui.tool.gis.Region;
import com.dituhui.tool.util.StringUtil;
import com.supermap.data.CursorType;
import com.supermap.data.DatasetVector;
import com.supermap.data.Datasource;
import com.supermap.data.DatasourceConnectionInfo;
import com.supermap.data.EngineType;
import com.supermap.data.GeoPoint;
import com.supermap.data.GeoRegion;
import com.supermap.data.Geometry;
import com.supermap.data.Point2D;
import com.supermap.data.Point2Ds;
import com.supermap.data.QueryParameter;
import com.supermap.data.Recordset;

/**
 * UDB工具。 UDB是超图格式的GIS数据文件。依赖SuperMap Object Java。
 * 
 * @author liweigu
 * 
 */
public class UDBTool {
	private static Logger LOGGER = Logger.getLogger(UDBTool.class);
	private static String Region = "region";
	private String udbFilePath;
	private Datasource datasource;

	public UDBTool(String udbFilePath) {
		this.init(udbFilePath);
		this.udbFilePath = udbFilePath;
	}

	private boolean init(String file) {
		// 打开工作空间
		DatasourceConnectionInfo datasourceConnectionInfo = new DatasourceConnectionInfo();
		datasourceConnectionInfo.setEngineType(EngineType.UDB);
		datasourceConnectionInfo.setServer(file);
		datasourceConnectionInfo.setReadOnly(true);
		this.datasource = new Datasource(EngineType.UDB);
		boolean flag = this.datasource.open(datasourceConnectionInfo);
		if (!flag) {
			LOGGER.warn("打开UDB数据源[" + file + "]失败");
		}
		return flag;
	}

	/**
	 * 查询
	 * 
	 * @param datasetVectorName 数据集名称
	 * @param sql 查询条件
	 * @param fildNames 查询字段名称
	 * @param hasGeometry 是否查询空间数据。如果为true，空间数据以"region"字段返回。
	 * @return
	 */
	public List<HashMap<String, String>> query(String datasetVectorName, String sql, String[] fildNames, boolean hasGeometry) {
		List<HashMap<String, String>> records = new ArrayList<HashMap<String, String>>();

		DatasetVector datasetVector = (DatasetVector) this.datasource.getDatasets().get(datasetVectorName);
		if (datasetVector == null) {
			LOGGER.info("[" + this.udbFilePath + "]datasetVector(" + datasetVectorName + ") is null");
		} else {
			// 设置查询参数
			QueryParameter parameter = new QueryParameter();
			parameter.setCursorType(CursorType.STATIC);
			parameter.setHasGeometry(hasGeometry);
			parameter.setAttributeFilter(sql);

			// 进行查询
			Recordset recordset = datasetVector.query(parameter);
			int recordCount = recordset.getRecordCount();
			// System.out.println("recordCount = " + recordCount);
			recordset.moveFirst();
			for (int i = 0; i < recordCount; i++) {
				HashMap<String, String> record = new HashMap<String, String>();
				for (String fildName : fildNames) {
					String value = recordset.getString(fildName);
					record.put(fildName, value);
				}
				if (hasGeometry) {
					Geometry geometry = recordset.getGeometry();
					GeoRegion geoRegion = (GeoRegion) geometry;
					int partCount = geoRegion.getPartCount();
					if (partCount > 0) {
						List<Point> points = new ArrayList<Point>();
						int[] parts = new int[partCount];
						for (int j = 0; j < partCount; j++) {
							Point2Ds point2Ds = geoRegion.getPart(j);
							int pointCount = point2Ds.getCount();
							Point2D firstPoint2D = point2Ds.getItem(0);
							for (int k = 0; k < pointCount; k++) {
								Point2D point2D = point2Ds.getItem(k);
								// 坐标是摩卡托格式
								double x = point2D.getX();
								double y = point2D.getY();
								points.add(new Point(x, y));
							}
							Point2D lastPoint2D = point2Ds.getItem(pointCount - 1);
							if (firstPoint2D.getX() != lastPoint2D.getX() || firstPoint2D.getY() != lastPoint2D.getY()) {
								// 最后一个点要跟第一个点重合，因此增加一个点
								points.add(new Point(firstPoint2D.getX(), firstPoint2D.getY()));
								parts[j] = pointCount + 1;
							} else {
								parts[j] = pointCount;
							}
//							if("150000".equals(record.get("admincode"))){
//								System.out.println("pointCount=" + pointCount + ",parts["+j+"]=" + parts[j]);
//							}
						}
//						if("150000".equals(record.get("admincode"))){
//							System.out.println("points.size()=" + points.size());
//						}
						Region region = new Region(points, parts);
						record.put(Region, region.toString());
					} else {
						LOGGER.warn("recordset(" + i + "),geoRegion.getPartCount() = " + partCount);
					}
				}
				records.add(record);
				recordset.moveNext();
			}

			// 依次关闭所有对象
			recordset.close();
			recordset.dispose();
		}

		return records;
	}

	public GeoRegion getGeoRegion(String datasetVectorName, GeoPoint point) {
		Geometry geometry = null;

		DatasetVector datasetVector = (DatasetVector) this.datasource.getDatasets().get(datasetVectorName);
		if (datasetVector == null) {
			LOGGER.debug("datasetVector(" + datasetVectorName + ") is null");
		} else {
			// 设置查询参数
			QueryParameter parameter = new QueryParameter();
			parameter.setCursorType(CursorType.STATIC);
			// setSpatialQueryMode(SpatialQueryMode.INTERSECT);
			parameter.setHasGeometry(false);
			// parameter.setSpatialQueryObject(point);
			// parameter.setAttributeFilter("CITY = '昌都县'");
			parameter.setAttributeFilter("smID = 7727");

			// 进行查询
			// System.out.println("start query");
			long startTime = System.currentTimeMillis();
			Recordset recordset = datasetVector.query(parameter);
			long endTime = System.currentTimeMillis();
			System.out.println("query time(ms): " + (endTime - startTime));
			int recordCount = recordset.getRecordCount();
			System.out.println("recordCount = " + recordCount);
			recordset.moveFirst();
			for (int i = 0; i < recordCount; i++) {
				String smID = recordset.getString("SmID");
				// System.out.println("smID = " + smID);
				String ID = recordset.getString("ID");
				// System.out.println("ID = " + ID);
				String AREAID = recordset.getString("AREAID");
				// System.out.println("AREAID = " + AREAID);
				String CITY = recordset.getString("CITY");
				// System.out.println("CITY = " + CITY);
				String AREANUMBER = recordset.getString("AREANUMBER");
				// System.out.println("AREANUMBER = " + AREANUMBER);
				// geometry = recordset.getGeometry();
				recordset.moveNext();
			}
			// endTime = System.currentTimeMillis();
			// System.out.println("total time(ms): " + (endTime - startTime));

			// 依次关闭所有对象
			recordset.close();
			recordset.dispose();
		}

		return (GeoRegion) geometry;
	}

	public void destroy() {
		if (this.datasource != null) {
			this.datasource.close();
		}
	}

}
